package com.funnyx.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ZkLockService implements InitializingBean {

  private static final String ROOT_PATH = "/";
  private static final String LOCK_PATH = "/lock";

  @Autowired private CuratorFramework curator;

  @Override
  public void afterPropertiesSet() throws Exception {
    if (curator.checkExists().forPath(LOCK_PATH) == null) {
      curator.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(LOCK_PATH);
      log.info("Create Node [{}] Successfully!", LOCK_PATH);
    }
  }

  public InterProcessMutex getInterProcessMutex(String lockPath) {
    return new InterProcessMutex(curator, lockPath);
  }

  public void lock(InterProcessMutex lock, Long time, TimeUnit unit) {
    try {
      if (time == null && unit == null) {
        lock.acquire();
      } else if (time != null && unit != null) {
        lock.acquire(time, unit);
      }
    } catch (Exception e) {
      log.error("Lock with an exception:{}", e.getMessage());
    }
  }

  public void release(InterProcessMutex lock) {
    try {
      lock.release();
    } catch (Exception e) {
      log.error("Release with an exception:{}", e.getMessage());
    }
  }
}
